<template>
  <div
    class="mpd-scroll-container"
    @mouseover="mouseIn = true"
    @mouseout="mouseIn = false"
    :class="[visible ? 'visible' : 'invisible']"
    :style="style"
    ref="container"
  >
    <div class="mpd-scroll-body" @mousewheel.passive="mouseWheelHandler" ref="body">
      <div class="mpd-scroll-view" ref="view">
        <slot></slot>
      </div>
    </div>
    <scroll-thumb
      v-if="showBar.indexOf('top') !== -1"
      position="top"
      :wheel="wheelX"
      :listenerResize="listenerResize"
    ></scroll-thumb>
    <scroll-thumb
      v-if="showBar.indexOf('bottom') !== -1"
      position="bottom"
      :wheel="wheelX"
      :listenerResize="listenerResize"
    ></scroll-thumb>
    <scroll-thumb
      v-if="showBar.indexOf('right') !== -1"
      position="right"
      :wheel="wheelY"
      :listenerResize="listenerResize"
    ></scroll-thumb>
    <scroll-thumb
      v-if="showBar.indexOf('left') !== -1"
      position="left"
      :wheel="wheelY"
      :listenerResize="listenerResize"
    ></scroll-thumb>
  </div>
</template>

<script>
import './scroll-container.less'
import ScrollThumb from './ScrollThumb.vue'
import { positionArrays } from './constant'
// https://github.com/tangdaohai/vue-happy-scroll/blob/master/src/strip.vue

export default {
  name: 'ScrollContainer',
  components: {
    ScrollThumb
  },
  props: {
    // 容器宽度
    width: {
      type: String,
      default: '100%'
    },
    // 容器高度
    height: {
      type: String,
      default: '100%'
    },
    // 需要展示的滚动条
    showBar: {
      type: Array,
      default() {
        return ['right', 'bottom']
      },
      validator: (value) => value.every((item) => positionArrays.indexOf(item) !== -1)
    },
    // 鼠标移动到dom的时候才显示滚动条
    hoverShowBar: {
      type: Boolean,
      default: true
    }
  },
  emits: ['size-change'],
  data() {
    return {
      // 鼠标是否在元素上
      mouseIn: false,
      // X轴滚轮偏移量
      wheelX: 0,
      // Y轴滚轮偏移量
      wheelY: 0,
      // view改变大小的时候改变该值
      listenerResize: true,
      // 监听view的对象
      mutationObserver: null
    }
  },
  computed: {
    style() {
      let style = {
        width: this.width,
        height: this.height
      }
      return style
    },
    // 计算是否隐藏显示滚动条
    visible() {
      if (this.mouseIn || !this.hoverShowBar) {
        return true
      } else {
        return false
      }
    }
  },
  methods: {
    mouseWheelHandler(event) {
      // 按下shift表示横向
      if (event.shiftKey) {
        this.wheelX += event.deltaY
      } else {
        this.wheelY += event.deltaY
      }
    },
    resizeHandler() {
      this.$emit('size-change')
      this.listenerResize = !this.listenerResize
    }
  },
  mounted() {
    // 监听视图大小变化
    // 观察器的配置（需要观察什么变动）
    const config = { attributes: true, childList: true, characterData: true, subtree: true }
    // 创建一个观察器实例并传入回调函数
    this.mutationObserver = new MutationObserver(this.resizeHandler)
    // 以上述配置开始观察目标节点
    this.mutationObserver.observe(this.$refs.container, config)
  },
  beforeDestroy() {
    // 之后，可停止观察
    this.mutationObserver.disconnect()
  }
}
</script>
